\newpage

\section*{Soluzione}

\subsection*{Es. 1}

Per risolvere il primo punto vi sono possibili alternative. Infatti si pu\`o
implementare un solo funtore, il cui metodo di accesso $()$ permette di
valutare la funzione e possiede un ulteriore metodo che restituisce la
primitiva della funzione. Il difetto di tale implementazione \`e dovuto al
fatto che viene richiesta esplicitamente la primitiva dell'integranda,
difficile se non impossibile da calcolare in molti casi pratici.
Un modo alternativo \`e costruire due funtori differenti che implementano la
valutazione dell'integranda o la valutazione della primitiva. 
Infine \`e possibile costruire una sola classe funtore che permette di
memorizzare al suo interno un puntatore a funzione, che memorizza la funzione
integranda o la sua primitiva. La scelta di quale di queste ultime due 
strategia dipende dal problema in questione. La seconda
strategia risulta leggermente meno efficiente, in quanto il metodo di accesso
$()$ richiama, a sua volta, una funzione esterna. La soluzione qui riporta si
basa sulla seconda strategia.\\
Riportiamo qui di seguito il listato contenente il \cpp{main} del programma e
l'implementazione dei funtori. Una implementazione migliore consiste nello 
scrivere i funtori in un file differente.

\lstset{basicstyle=\scriptsize\sf}
\lstinputlisting[caption=Listato contenente il \cpp{main} e i funtori]{es/sol/main_integration.cpp}
\lstset{basicstyle=\sf}

Per poter utilizzare il metodo \cpp{apply}, della classe \cpp{Quadrature},
anche con i funtori implementati le strategie sono molteplici. 
Il primo approccio pi\`u semplice risulta nel riscrive il
metodo appositamente per i funtori, soluzione applicabile solo nel caso in cui
i funtori contengono il puntatore a funzione. In questo modo
l'\textit{overloading} di \cpp{apply} \`e fatto solamente una volta. 
Un secondo approccio utilizza i template, trasformando il metodo \cpp{apply} in
un metodo template. In questo modo l'unica richiesta che viene fatta sul
parametro template \`e che riesce a implementa l'operatore $()$. 
Infine \`e possibile implementare per la classe funtore un operatore di casting
in una funzione di tipo \cpp{FunPoint}.
Tale soluzione risulta piuttosto complessa, quindi si \`e scelto di
implementare l'approccio che utilizza i template, essendo anche pi\`u generale.
\`E importante notare che il metodo \cpp{apply} diviene un metodo template,
mentre la classe \cpp{Quadrature} rimane una classe non template. 
Per questo fatto si \`e obbligati ad inserire l'implementazione del metodo
\cpp{apply} direttamente  all'interno dell'\textit{header file}.\\
La selezione del tipo identificato dal template viene fatto in fase di
compilazione, inoltre il compilatore verifica che il tipo possiede tutte le
funzionalit\`a richieste dal metodo \cpp{apply}. In fase di esecuzione il
programma conosce esattamente il tipo e non fa alcun controllo. Utilizzare i
template permette di ottenere un programma molto pi\`u flessibile ma la fase
di compilazione risulta pi\`u onerosa. Va infine fatto notare che solo le
classi e funzioni template che vengono effettivamente utilizzate vengono
compilate, in quanto il compilatore non conosce il tipo dei parametri template
coinvolti nelle classi e funzioni non utilizzati.

\lstset{basicstyle=\scriptsize\sf}
\lstinputlisting[caption=Listato contenente l'implementazione della classe \cpp{Quadrature} con il metodo \cpp{apply} template]{es/sol1/numerical_integration.hpp}
\lstset{basicstyle=\sf}

Un modo alternativo di gestire il polimorfismo per memorizzare un attributo,
all'interno di una classe, \`e trasformare la classe \cpp{Quadrature} in una 
classe template. Il motivo che ora la classe \cpp{Quadrature} diviene template,
mentre nel caso precedente solo il metodo \cpp{apply} \`e divenuto template,
\`e il fatto che ora la classe memorizza un attributo template, 
mentre prima utilizzava un parametro template esterno. 
Essendo la classe \cpp{Quadrature} template, tutti i metodi che implementa
devono essere contenuti in un \textit{header file}. Da notare l'implementazione
del metodo \cpp{apply} che deve tenere conto sia del parametro template della 
classe che del parametro template. \`E possibile, per una classe template, 
fornire dei valori di default template. Come nel caso dei 
parametri di default per una funzione, \`e consigliato lasciare i parametri 
template con valore di default alla fine delle lista dei parametri template.

\lstset{basicstyle=\scriptsize\sf}
\lstinputlisting[caption=Listato contenente l'implementazione della classe template \cpp{Quadrature} con il metodo \cpp{apply} template]{es/sol/src/numerical_integration.hpp}
\lstset{basicstyle=\sf}